package com.sun.mybatisplus.rabbitmq.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**
 * @Auth: syh
 * @Date: 2021/10/22 15:24
 * @Email: 1014170249@qq.com
 * @Desc: 不在能知，而在能行
 * 模拟用户下订单
 */
@Service
@Slf4j
public class OrderService {


    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 模拟用户下单 Fanout模式
     * @param userId
     * @param productId
     * @param productNum
     */
    public void makeOrder(String userId,String productId,int productNum){
        //查询库存是否充足
        //保存订单
        String orderId = UUID.randomUUID().toString();
        log.info("创建订单成功，订单id:{}",orderId);
        //通过mq来实现消息的分发
        rabbitTemplate.convertAndSend("order_exchange","",orderId);
    }


    /**
     * 模拟用户下单 Direct模式
     * @param userId
     * @param productId
     * @param productNum
     */
    public void makeOrderDirect(String userId,String productId,int productNum){
        //查询库存是否充足
        //保存订单
        String orderId = UUID.randomUUID().toString();
        log.info("创建订单成功，订单id:{}",orderId);
        //通过mq来实现消息的分发 给sms发送消息
        rabbitTemplate.convertAndSend("direct_exchange","sms",orderId);
    }


    /**
     * 模拟用户下单 Topic模式（主题模式）
     * @param userId
     * @param productId
     * @param productNum
     */
    public void makeOrderTopic(String userId,String productId,int productNum){
        //查询库存是否充足
        //保存订单
        String orderId = UUID.randomUUID().toString();
        log.info("创建订单成功，订单id:{}",orderId);
        //通过mq来实现消息的分发 给sms发送消息
        rabbitTemplate.convertAndSend("topic_exchange","sun.duanxin.com",orderId);
    }


    /**
     * 模拟用户下单  设置队列的过期时间
     * @param userId
     * @param productId
     * @param productNum
     */
    public void makeOrderTTL(String userId,String productId,int productNum){
        //查询库存是否充足
        //保存订单
        String orderId = UUID.randomUUID().toString();
        log.info("TTL创建订单成功，订单id:{}",orderId);
        //通过mq来实现消息的分发 给sms发送消息
        rabbitTemplate.convertAndSend("ttl_direct_exchange","ttl",orderId);
    }


    /**
     * 模拟用户下单  设置消息的过期时间
     * @param userId
     * @param productId
     * @param productNum
     */
    public void makeOrderTTLMessage(String userId,String productId,int productNum){
        //查询库存是否充足
        //保存订单
        String orderId = UUID.randomUUID().toString();
        log.info("TTL创建订单成功，订单id:{}",orderId);

        //给消息设置过期时间
        MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setExpiration("5000"); //设置5秒
                message.getMessageProperties().setContentEncoding("utf-8");
                return message;
            }
        };
        //通过mq来实现消息的分发 给sms发送消息
        rabbitTemplate.convertAndSend("ttl_direct_exchange","ttlmessage",orderId,messagePostProcessor);
    }


    /**
     * ****************************************************************************************************************
     * 需要明确的概念：
     * 设置队列的过期时间，有个标识TTL.一旦队列过期后，队列并不会马上消失，而是放入到死信队列中；
     * 而设置消息的过期时间，一旦过期，消息就会被删除。
     * ****************************************************************************************************************
     *
     * DLX: 全称为Dead Letter Exchange死信交换机。或者叫做死信邮箱。当消息在一个队列中成为死信时，他可能会被重新发到另外一个交换机中
     * 这个交换机就是死信交换机。与死信交换机绑定的队列就是就是死信队列。消息就变成死信。
     * 造成死信的原因：
     *  1、消息被拒绝
     *  2、消息过期
     *  3、队列达到最大长度
     */


}
